package com.jojo.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jojo.domain.SysRole;
import com.jojo.domain.SysUser;
import com.jojo.domain.SysUserRole;
import com.jojo.mapper.SysUserMapper;
import com.jojo.mapper.SysUserRoleMapper;
import com.jojo.service.SysUserRoleService;
import com.jojo.service.SysUserService;
import com.jojo.util.AuthUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {

    @Resource
    private SysUserMapper sysUserMapper;

    @Resource
    private SysUserRoleMapper sysUserRoleMapper;

    /*批量操作在业务层中*/
    @Autowired
    private SysUserRoleService sysUserRoleService;

    @Resource
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    /**
     * 1.新增管理员
     * 2.新增管理员与角色的关系
     *
     * 修改数据需要加上事务
     *
     * @param sysUser
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer saveSysUser(SysUser sysUser) {
        //新增管理员
        sysUser.setCreateUserId(AuthUtils.getLoginUserId());
        sysUser.setCreateTime(new Date());
        sysUser.setShopId(1L);
        sysUser.setPassword(bCryptPasswordEncoder.encode(sysUser.getPassword()));
        int i = sysUserMapper.insert(sysUser);
        if (i > 0) {
            //获取管理员的标识
            Long userId = sysUser.getUserId();
            //新增管理员与角色的关系
            //获取管理员的角色id集合
            List<Long> roleIdList = sysUser.getRoleIdList();
            //判断是否有值
            if (CollectionUtil.isNotEmpty(roleIdList) && roleIdList.size() != 0) {
                //创建管理员与角色关系的集合
                List<SysUserRole> list = new ArrayList<>();
                //循环遍历角色id集合
                roleIdList.forEach(roleId -> {
                    //新增管理员与角色之间的关系
                    SysUserRole sysUserRole = SysUserRole.builder().roleId(roleId).userId(userId).build();
                    /*  注意:  不建议在循环中操作数据库  */
                    /*sysUserRoleMapper.insert(sysUserRole);*/
                    list.add(sysUserRole);
                });
                //使用批量加入
                sysUserRoleService.saveBatch(list);
            }
        }
        return i;
    }

    @Override
    public SysUser querySysUserInfoByUserId(Long id) {
        //根据标识查询管理员信息
        SysUser sysUser = sysUserMapper.selectById(id);
        //根据用户标识查询管理员与角色的关系集合
        List<SysUserRole> sysUserRoles = sysUserRoleMapper.selectList(new LambdaQueryWrapper<SysUserRole>()
                .eq(SysUserRole::getUserId, id)
        );
        //判断是否有值
        if (CollectionUtil.isNotEmpty(sysUserRoles)) {
            //从管理员与角色集合中获取角色的id集合
            List<Long> roleIdList = sysUserRoles.stream().map(SysUserRole::getRoleId).collect(Collectors.toList());
            sysUser.setRoleIdList(roleIdList);
        }
        return sysUser;
    }

    /**
     * 修改管理员信息
     * 1.删除原有的管理员与角色的关系记录
     * 2.添加新的管理员和关系记录
     * 3.修改管理员信息
     *
     * @param sysUser
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer modifySysUserInfo(SysUser sysUser) {
        //获取管理员标识
        Long loginUserId = AuthUtils.getLoginUserId();
        //删除原有的管理员和角色关系记录
        sysUserRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>()
                .eq(SysUserRole::getUserId, loginUserId)
        );
        //添加管理员与角色关系记录
        /* 与上述新增逻辑相同 */
        //获取管理员的角色id集合
        List<Long> roleIdList = sysUser.getRoleIdList();
        //判断是否有值
        if (CollectionUtil.isNotEmpty(roleIdList) && roleIdList.size() != 0) {
            //创建管理员与角色关系的集合
            List<SysUserRole> list = new ArrayList<>();
            //循环遍历角色id集合
            roleIdList.forEach(roleId -> {
                //新增管理员与角色之间的关系
                SysUserRole sysUserRole = SysUserRole.builder().roleId(roleId).userId(loginUserId).build();
                /*  注意:  不建议在循环中操作数据库  */
                /*sysUserRoleMapper.insert(sysUserRole);*/
                list.add(sysUserRole);
            });
            //使用批量加入
            sysUserRoleService.saveBatch(list);
        }
        //修改管理员信息
        //获取新密码（如果有值，说明管理员修改了新密码，如果没有值，说明原密码不变）
        String password = sysUser.getPassword();
        if (StringUtils.hasText(password)) {
            //有值，说明要修改密码(需要加密)
            sysUser.setPassword(bCryptPasswordEncoder.encode(password));
        }
        return sysUserMapper.updateById(sysUser);
    }

    /**
     * 批量/单个删除管理员信息
     * 1.批量/单个删除管理员和角色之间的关系
     * 2.批量/单个删除管理员信息
     * @param userIds
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean removeSysUserListByUserIds(List<Long> userIds) {
        //批量/单个删除管理员和角色之间的关系
        sysUserRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>()
                .in(SysUserRole::getUserId,userIds)
        );
        //批量或单个删除管理员
        return sysUserMapper.deleteBatchIds(userIds) == userIds.size();
    }
}